package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.config.VodConstantProperties;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.common.util.UploadFileUtil;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.math.BigDecimal;
import java.nio.channels.MulticastChannel;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

    @Autowired
    private TrackInfoMapper trackInfoMapper;
    @Autowired
    private VodConstantProperties vodConstantProperties;
    @Autowired
    private VodService vodService;
    @Autowired
    private TrackStatMapper trackStatMapper;
    @Autowired
    private AlbumInfoService albumInfoService;
    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    /**
     * 上传声音
     *
     * @param file
     * @return
     */
    @Override
    public UploadTrackVo uploadTrack(MultipartFile file) {
        //创建客户端对象
        VodUploadClient client = new VodUploadClient(vodConstantProperties.getSecretId(), vodConstantProperties.getSecretKey());

        //构造上传请求对象

        String filePath = UploadFileUtil.uploadTempPath(vodConstantProperties.getTempPath(), file);

        VodUploadRequest request = new VodUploadRequest();
        request.setMediaFilePath(filePath);
        request.setProcedure(vodConstantProperties.getTempPath());

        try {
            VodUploadResponse response = client.upload(vodConstantProperties.getRegion(), request);
            UploadTrackVo uploadTrackVo = new UploadTrackVo();
            uploadTrackVo.setMediaFileId(response.getFileId());
            uploadTrackVo.setMediaUrl(response.getMediaUrl());
            return uploadTrackVo;

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //删除临时文件
            new File(filePath).delete();
        }
    }

    /**
     * 保存声音信息
     *
     * @param trackInfoVo
     */
    @Override
    @Transactional
    public void saveTrackInfo(TrackInfoVo trackInfoVo) {
        TrackInfo trackInfo = new TrackInfo();
        Long userId = AuthContextHolder.getUserId();
        trackInfo.setUserId(userId);
        BeanUtils.copyProperties(trackInfoVo, trackInfo);
        //需要查询该用户的此专辑中有多少声音，+1设置为当前序号
        LambdaQueryWrapper<TrackInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TrackInfo::getAlbumId, trackInfoVo.getAlbumId());
        queryWrapper.orderByDesc(TrackInfo::getOrderNum);
        queryWrapper.last("limit 1");
        TrackInfo trackInfo1 = trackInfoMapper.selectOne(queryWrapper);
        if (trackInfo1 == null) {
            trackInfo.setOrderNum(1);
        } else {
            Integer orderNum = trackInfo1.getOrderNum();
            orderNum++;
            trackInfo.setOrderNum(orderNum);
        }

        //需要根据媒体文件id调用腾讯云接口查询媒体时长，文件大小，文件类型
        TrackMediaInfoVo mediaInfo = vodService.getMediaInfo(trackInfoVo.getMediaFileId());
        trackInfo.setMediaDuration(BigDecimal.valueOf(mediaInfo.getDuration()));
        trackInfo.setMediaUrl(mediaInfo.getMediaUrl());
        trackInfo.setMediaSize(mediaInfo.getSize());
        trackInfo.setMediaType(mediaInfo.getType());

        trackInfo.setSource(SystemConstant.TRACK_SOURCE_UPLOAD);
        trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);

        //保存到数据库
        trackInfoMapper.insert(trackInfo);

        //保存声音统计数据
        savaTrackStat(SystemConstant.TRACK_STAT_PLAY, trackInfo.getId());
        savaTrackStat(SystemConstant.TRACK_STAT_COLLECT, trackInfo.getId());
        savaTrackStat(SystemConstant.TRACK_STAT_PRAISE, trackInfo.getId());
        savaTrackStat(SystemConstant.TRACK_STAT_COMMENT, trackInfo.getId());

        //更改专辑表中include_track_count数量
        AlbumInfo albumInfo = albumInfoService.getById(trackInfoVo.getAlbumId());
        Integer includeTrackCount = albumInfo.getIncludeTrackCount();
        albumInfo.setIncludeTrackCount(includeTrackCount + 1);
        albumInfoService.updateById(albumInfo);


    }


    /**
     * 分页查询用户声音
     *
     * @param pageNo
     * @param pageSize
     * @param trackInfoQuery
     * @return
     */
    @Override
    public IPage<TrackListVo> findUserTrackPage(Long pageNo, Long pageSize, TrackInfoQuery trackInfoQuery) {
        Page<TrackListVo> page = new Page<>(pageNo, pageSize);
        trackInfoQuery.setUserId(AuthContextHolder.getUserId());
        return trackInfoMapper.findUserTrackPage(page, trackInfoQuery);
    }

    /**
     * 修改声音
     *
     * @param id
     * @param trackInfoVo
     */
    @Override
    public void updateTrackInfo(Long id, TrackInfoVo trackInfoVo) {
        TrackInfo trackInfo = trackInfoMapper.selectById(id);
        String mediaFileId = trackInfoVo.getMediaFileId();
        String mediaFileId1 = trackInfo.getMediaFileId();
        //判断用户是否修改了媒体文件
        if (!mediaFileId.equals(mediaFileId1)) {
            //修改了媒体文件
            TrackMediaInfoVo mediaInfo = vodService.getMediaInfo(mediaFileId);
            trackInfo.setMediaDuration(BigDecimal.valueOf(mediaInfo.getDuration()));
            trackInfo.setMediaUrl(mediaInfo.getMediaUrl());
            trackInfo.setMediaSize(mediaInfo.getSize());
            trackInfo.setMediaType(mediaInfo.getType());

            //todo:把之前的媒体文件删除
            vodService.deleteMedia(mediaFileId1);
        }
        BeanUtils.copyProperties(trackInfoVo, trackInfo);
        //修改数据库
        trackInfoMapper.updateById(trackInfo);


    }

    /**
     * 删除声音
     *
     * @param id
     */
    @Override
    public void removeTrackInfo(Long id) {
        //删除声音数据
        TrackInfo trackInfo = trackInfoMapper.selectById(id);
        String mediaFileId = trackInfo.getMediaFileId();
        trackInfoMapper.deleteById(id);

        //删除声音统计数据
        LambdaQueryWrapper<TrackStat> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TrackStat::getTrackId, id);
        trackStatMapper.delete(queryWrapper);

        //todo:删除腾讯云媒体文件
        vodService.deleteMedia(mediaFileId);

        //更改专辑表中include_track_count数量
        AlbumInfo albumInfo = albumInfoService.getById(trackInfo.getAlbumId());
        Integer includeTrackCount = albumInfo.getIncludeTrackCount();
        albumInfo.setIncludeTrackCount(includeTrackCount - 1);
        albumInfoService.updateById(albumInfo);

    }

    /**
     * 根据专辑id查询专辑下的声音
     *
     * @param albumId
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public IPage<AlbumTrackListVo> findAlbumTrackPage(Long albumId, Integer pageNo, Integer pageSize) {
        Page<AlbumTrackListVo> page = new Page<>(pageNo, pageSize);
        page = trackInfoMapper.findAlbumTrackPage(page, albumId);

        List<AlbumTrackListVo> albumTrackListVos = page.getRecords();
        //获取专辑数据
        AlbumInfo albumInfo = albumInfoService.getAlbumInfo(albumId);
        //判断用户是否登录
        if (AuthContextHolder.getUserId() == null) {
            //用户未登录判断是否是免费专辑
            if (!albumInfo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_FREE)) {
                //不是免费专辑设置试听声音
                albumTrackListVos.stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree())
                        .forEach(albumTrackListVo -> albumTrackListVo.setIsShowPaidMark(true));
            }
        } else {
                //不是免费专辑判断是否是vip专辑
                if (albumInfo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_VIPFREE)) {
                    //是vip专辑判断用户是否是vip
                    UserInfoVo userInfoVo = userInfoFeignClient.getUserInfo(AuthContextHolder.getUserId()).getData();
                    if (userInfoVo.getIsVip() != 1) {
                        //不是VIP用户直接试听
                        albumTrackListVos.stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree())
                                .forEach(albumTrackListVo -> albumTrackListVo.setIsShowPaidMark(true));
                    } else {
                        //判断用户VIP是否过期
                        Date vipExpireTime = userInfoVo.getVipExpireTime();
                        if (vipExpireTime.before(new Date())) {
                            //过期直接试听
                            albumTrackListVos.stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree())
                                    .forEach(albumTrackListVo -> albumTrackListVo.setIsShowPaidMark(true));
                        }
                    }
                }
                //判断是否是付费专辑
                if (albumInfo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_REQUIRE)) {
                    //设置试听
                    albumTrackListVos.stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree())
                            .forEach(albumTrackListVo -> albumTrackListVo.setIsShowPaidMark(true));
                    //判断用户是否购买过专辑
                    List<Long> trackIds = albumTrackListVos.stream().map(AlbumTrackListVo::getTrackId).toList();
                    Map<Long, Integer> data = userInfoFeignClient.userIsPaidTrack(albumId, trackIds).getData();
                    albumTrackListVos.stream().forEach(albumTrackListVo -> {
                        if (data.get(albumTrackListVo.getTrackId()) == 1) {
                            albumTrackListVo.setIsShowPaidMark(false);
                        }
                    });
                }

        }
        return page;
    }


    public void savaTrackStat(String statType, Long trackId) {
        TrackStat trackStat = new TrackStat();
        trackStat.setTrackId(trackId);
        trackStat.setStatType(statType);
        trackStat.setStatNum(0);

        trackStatMapper.insert(trackStat);
    }
}
